package com.alex.statistics.method.descriptive;

import com.alex.statistics.pojo.result.descriptive.CentralTendencyResult;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 集中趋势分析
 */
@Component
public class CentralTendencyAnalyzer {

    // 计算均值（Mean）
    private double calculateMean(List<Double> data) {
        if (data == null || data.isEmpty()) {
            throw new IllegalArgumentException("数据不能为空或长度为0");
        }
        return data.stream()
                .mapToDouble(Double::doubleValue)
                .average()
                .orElse(0.0);
    }

    // 计算中位数（Median）
    private double calculateMedian(List<Double> data) {
        if (data == null || data.isEmpty()) {
            throw new IllegalArgumentException("数据不能为空或长度为0");
        }
        List<Double> sortedData = data.stream()
                .sorted()
                .toList();
        int middle = sortedData.size() / 2;
        if (sortedData.size() % 2 == 0) {
            return (sortedData.get(middle - 1) + sortedData.get(middle)) / 2.0;
        } else {
            return sortedData.get(middle);
        }
    }

    // 计算众数（Mode），返回所有众数（可能有多个）
    private List<Double> calculateMode(List<Double> data) {
        if (data == null || data.isEmpty()) {
            throw new IllegalArgumentException("数据不能为空或长度为0");
        }
        // 统计频率
        Map<Double, Long> frequencyMap = data.stream()
                .collect(Collectors.groupingBy(d -> d, Collectors.counting()));
        // 找到最高频率
        long maxFrequency = Collections.max(frequencyMap.values());
        // 收集所有众数
        return frequencyMap.entrySet().stream()
                .filter(entry -> entry.getValue() == maxFrequency)
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());
    }

    // 集中趋势分析
    public CentralTendencyResult analyze(List<Double> numbers) {
        CentralTendencyResult centralTendencyResult = new CentralTendencyResult();
        centralTendencyResult.setMean(calculateMean(numbers));
        centralTendencyResult.setMedian(calculateMedian(numbers));
        centralTendencyResult.setMode(calculateMode(numbers));
        return centralTendencyResult;
    }




}

